using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Runtime.Serialization;

namespace ContractDocumentation
{
    [DataContract(Namespace = "http://cz.o2.com/ContractDocumentation")]
    class XmlClass
    {
        private XName name;
        [DataMember(Order = 1)]
        public XName Name
        {
            get { return name; }
            set { name = value; }
        }

        private string documentation;
        [DataMember(Order = 2)]
        public string Documentation
        {
            get { return documentation; }
            set { documentation = value; }
        }

        private IList<XmlMethod> methods;
        [DataMember(Order = 3)]
        public IList<XmlMethod> Methods
        {
            get { return methods; }
            set { methods = value; }
        }

        public override string ToString()
        {
            return Name.ToString();
        }
    }

    [DataContract(Namespace = "http://cz.o2.com/ContractDocumentation")]
    class XmlMethod
    {
        private XName name;
        [DataMember(Order = 1)]
        public XName Name
        {
            get { return name; }
            set { name = value; }
        }

        private XmlParameter returnValue;
        [DataMember(Order = 2)]
        public XmlParameter ReturnValue
        {
            get { return returnValue; }
            set { returnValue = value; }
        }

        private string documentation;
        [DataMember(Order = 3)]
        public string Documentation
        {
            get { return documentation; }
            set { documentation = value; }
        }

        private IList<XmlParameter> parameters;
        [DataMember(Order = 4)]
        public IList<XmlParameter> Parameters
        {
            get { return parameters; }
            set { parameters = value; }
        }

        public override string ToString()
        {
            return Name.ToString();
        }
    }

    [DataContract(Namespace = "http://cz.o2.com/ContractDocumentation")]
    class XmlParameter
    {
        private XName name;
        [DataMember(Order = 1)]
        public XName Name
        {
            get { return name; }
            set { name = value; }
        }

        private XmlType xmlType;
        [DataMember(Order = 2)]
        public XmlType XmlType
        {
            get { return xmlType; }
            set { xmlType = value; }
        }

        private string documentation;
        [DataMember(Order = 3)]
        public string Documentation
        {
            get { return documentation; }
            set { documentation = value; }
        }

        public override string ToString()
        {
            return Name.ToString();
        }
    }

    [DataContract(Namespace = "http://cz.o2.com/ContractDocumentation")]
    class XmlType
    {
        private XName type;
        [DataMember(Order = 1)]
        public XName Type
        {
            get { return type; }
            set { type = value; }
        }

        private bool isArray;
        [DataMember(Order = 2)]
        public bool IsArray
        {
            get { return isArray; }
            set { isArray = value; }
        }

        public string GetSimpleName()
        {
            return type.LocalName + (IsArray ? "[]" : "");
        }

        public override string ToString()
        {
            return type + (IsArray ? "[]" : "");
        }
    }

    class XNameSurrogate : IDataContractSurrogate
    {
        public object GetCustomDataToExport(Type clrType, Type dataContractType)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public object GetCustomDataToExport(System.Reflection.MemberInfo memberInfo, Type dataContractType)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public Type GetDataContractType(Type type)
        {
            if (typeof(XName).IsAssignableFrom(type))
            {
                return typeof(string);
            }
            return type;
        }

        public object GetDeserializedObject(object obj, Type targetType)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection<Type> customDataTypes)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public object GetObjectToSerialize(object obj, Type targetType)
        {
            XName name = obj as XName;
            if (name != null)
            {
                return name.ToString();
            }
            return obj;
        }

        public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }

}
